#pragma once
#include <cstddef>
#include <odb/core.hxx>
#include <odb/nullable.hxx>
#include <string>

namespace ken_im
{
#pragma db object table( "user" )
/**
 * @class User
 * @brief 用户类，用于表示和管理用户信息。
 *
 * 该类提供了用户的基本信息，包括用户ID、昵称、密码、手机号、头像ID等。
 * 可以通过构造函数创建用户对象，并使用成员函数来设置和获取用户信息。
 *
 * 核心功能：
 * - 提供用户ID、昵称、密码、手机号、头像ID的设置和获取方法。
 * - 支持通过用户ID和手机号创建用户对象。
 *
 * 使用示例：
 * @code
 * User user1("user123", "John Doe", "password123");
 * User user2("user456", "12345678901");
 * std::string userId = user1.user_id();
 * std::string nickname = user2.nickname();
 * @endcode
 *
 * 构造函数：
 * - User()：默认构造函数，创建一个空的用户对象。
 * - User(const std::string &uid, const std::string &nickname, const std::string
 * &password)：通过用户ID、昵称和密码创建用户对象。
 * - User(const std::string &uid, const std::string
 * &phone)：通过用户ID和手机号创建用户对象，昵称默认为用户ID。
 *
 * 注意：
 * - 用户ID和手机号在数据库中是唯一的，不能重复。
 * - 用户昵称、密码、签名、手机号和头像ID是可选的，可以为空。
 */
class User
{
  public:
    User()
    {
    }
    // 用户名--新增用户 -- 用户ID, 昵称，密码
    User( const std::string &uid, const std::string &nickname,
          const std::string &password )
        : _user_id( uid ), _nickname( nickname ), _password( password )
    {
    }
    // 手机号--新增用户 -- 用户ID, 手机号, 随机昵称
    User( const std::string &uid, const std::string &phone )
        : _user_id( uid ), _nickname( uid ), _phone( phone )
    {
    }

    void user_id( const std::string &val )
    {
        _user_id = val;
    }
    std::string user_id()
    {
        return _user_id;
    }

    std::string nickname()
    {
        if ( _nickname )
            return *_nickname;
        return std::string();
    }
    void nickname( const std::string &val )
    {
        _nickname = val;
    }

    std::string description()
    {
        if ( !_description )
            return std::string();
        return *_description;
    }
    void description( const std::string &val )
    {
        _description = val;
    }

    std::string password()
    {
        if ( !_password )
            return std::string();
        return *_password;
    }
    void password( const std::string &val )
    {
        _password = val;
    }

    std::string phone()
    {
        if ( !_phone )
            return std::string();
        return *_phone;
    }
    void phone( const std::string &val )
    {
        _phone = val;
    }

    std::string avatar_id()
    {
        if ( !_avatar_id )
            return std::string();
        return *_avatar_id;
    }
    void avatar_id( const std::string &val )
    {
        _avatar_id = val;
    }

  private:
    friend class odb::access;

    /*
    通过 ODB,用 C++ 代码定义数据库表结构，而无需直接编写 SQL
    语句，这大大提高了开发效率和代码的可维护性。*/

    // 是一个自动生成的主键字段，用于唯一标识数据库中的每一条记录、
#pragma db id auto
    unsigned long _id;

#pragma db type( "varchar(64)" ) index unique
    std::string _user_id;

#pragma db type( "varchar(64)" ) index unique
    odb::nullable<std::string> _nickname; // 用户昵称-不一定存在

    odb::nullable<std::string> _description; // 用户签名 - 不一定存在

#pragma db type( "varchar(64)" )
    odb::nullable<std::string> _password; // 用户密码 - 不一定存在

#pragma db type( "varchar(64)" ) index unique // 唯一索引
    odb::nullable<std::string> _phone;        // 用户手机号 - 不一定存在

#pragma db type( "varchar(64)" )
    odb::nullable<std::string> _avatar_id; // 用户头像文件ID - 不一定存在
};
} // namespace ken_im

// odb -d mysql --std c++11 --generate-query --generate-schema --profile
// boost/date-time person.hxx